import SpawnController, { getCreeps } from '@/modules/structures/spawn'
import { hugeCrowdTask } from '../types'
import { CreepRoles } from '@/modules/structures/spawn/types'
import { defineGlobalProperty, generateId, interceptRoom } from '@/ayaka'
import { hugeCrowdWork } from './hugeCrowdWork'

/**
 * 人海战术控制器
 */
export default class HugeCrowdController {
    /**
     * 运行
     */
    public static run(room: MyRoom) {
        const { tasks } = HugeCrowdController.getMemory(room)
        tasks.forEach((task) => HugeCrowdController.execute(room, task))
    }

    /**
     * 执行任务
     */
    public static execute(room: MyRoom, task: hugeCrowdTask) {
        const { hugeCrowd } = task

        const hugeCrowds = getCreeps(room, hugeCrowd)
        if (hugeCrowd.length === 80) {
            task.spawnComplete = true
        } else if (!task.spawnComplete) {
            HugeCrowdController.spawnHugeCrowd(room, task)
        } else if (!hugeCrowds.length) {
            HugeCrowdController.delete(room, task.id)
            return
        }

        hugeCrowdWork(hugeCrowds, task)
    }

    /**
     * 获取 memory
     */
    public static getMemory(room: MyRoom) {
        if (!room.memory.war.hugeCrowd) {
            room.memory.war.hugeCrowd = {
                tasks: [],
            }
        }
        return room.memory.war.hugeCrowd
    }

    /**
     * 孵化人海
     */
    public static spawnHugeCrowd(room: MyRoom, task: hugeCrowdTask) {
        if (SpawnController.searchSpawnTaskByRole(room, CreepRoles.hugeCrowd).length) return

        const number = task.hugeCrowd.length

        const creepName = SpawnController.addSpawnTask(room, {
            role: CreepRoles.hugeCrowd,
            body: number < 20 ? [MOVE] : number < 50 ? [CARRY, MOVE] : [ATTACK, MOVE],
            memory: {
                taskId: number < 25 ? 'move' : number < 60 ? 'carry' : 'attack',
            },
        })

        if (!creepName) return
        task.hugeCrowd.push(creepName)
    }

    /**
     * 发布指定房间的人海战术任务
     */
    public static publish(room: MyRoom, task: hugeCrowdTask) {
        const memory = HugeCrowdController.getMemory(room)
        memory.tasks.push(task)
    }

    /**
     * 手动发布人海战术任务
     */
    @interceptRoom()
    public static add(myRoomName: string, targetRoomName: string) {
        const task: hugeCrowdTask = {
            id: generateId(),
            hugeCrowd: [],
            roomName: targetRoomName,
            range: 8,
        }
        HugeCrowdController.publish(Game.rooms[myRoomName] as MyRoom, task)
        return `人海战术任务 ${myRoomName} -> ${targetRoomName} 发布成功`
    }

    /**
     * 删除指定 id 的任务
     */
    public static delete(room: MyRoom, id: string) {
        const memory = HugeCrowdController.getMemory(room)
        memory.tasks = memory.tasks.filter((task) => task.id !== id)
    }
}

defineGlobalProperty('HugeCrowd', {
    value: HugeCrowdController,
})
